﻿using System;
using System.Collections.Generic;
using AdaptiveAgents.Agents.Choosers;
using AdaptiveAgents.Agents;
using AdaptiveAgents.Loggers;

namespace AdaptiveAgents.Agents.Choosers
{
    /// <summary>
    /// Represents a default chooser
    /// </summary>
    class NormalNextPlayerChooser : NextPlayerChooser
    {
        public NormalNextPlayerChooser(Agent agent)
            : base(agent)
        {
            agent.NextPlayerChooser = this;
        }

        public override int choose(int maxToConsider)
        {
            NumberOfAgents = _me.Environment.agents.Count;
            if (_me.ObservationsSet.observations.Count < _me.ChangeStrategyPoint)
            {
                //choose randomly the next player
                return Generator.getNextInt(NumberOfAgents);
            }

            double maxComp = -Double.MaxValue;
            Agent maxAgent = null;
            foreach (Agent agent in _me.Environment.agents)
            {
                if (agent.ID >= maxToConsider) break;
                double comp;
                if (agent.ID == _me.ID) // AGENTS know own competence
                    //comp = _me.Competence.getExpectedValue();
                    comp = _me.Competence.Mean;
                else
                    comp = _me.getTeammateModel(agent.ID).EstimateCompetence();
                AdaptiveAgents.logger.WriteLine(MessageType.OtherAgentCompetence, _me.ID, agent.ID, comp);

                int numTies = 1;
                if (comp > maxComp)
                {
                    maxComp = comp;
                    maxAgent = agent;
                    numTies = 1;
                }
                else if (Math.Abs(comp - maxComp) < .000001)
                {
                    numTies++;
                    AdaptiveAgents.logger.WriteLine(MessageType.AgentTied, numTies);

                    if (Generator.getNextDouble() < 1.0 / numTies)
                    {
                        maxAgent = agent;
                    }
                }
            }
            if (Generator.getNextDouble() >= _me.Epsilon)
            {
                AdaptiveAgents.logger.WriteLine(MessageType.HowChoosingNextPlayer, "Choosing deliberately");
                AdaptiveAgents.logger.WriteLine(MessageType.OtherAgentMaxCompetence, _me.ID, maxAgent.ID, maxComp);

                return maxAgent.ID;
            }
            else
            {
                int nextPlayer;
                int agents = _me.Environment.agents.Count;
                AdaptiveAgents.logger.WriteLine(MessageType.HowChoosingNextPlayer, "Choosing randomly");

                nextPlayer = (_me.ID + Generator.getNextInt(_me.Environment.agents.Count - 1) + 1) % _me.Environment.agents.Count;

                return nextPlayer; //Random selection
            }
        }
    }

}
